package in.ac.iitb.cse.nlp.postagger.data;

import java.util.HashMap;
import java.util.Map;

public class EmissionMatrix implements Matrix {

	// Internal map which stores the emission table
	private Map<Word, HashMap<Tag, Integer>> emissionTable = new HashMap<Word, HashMap<Tag, Integer>>();

	public void update(String row, String col) {
		Word word = DataMaps.words.get(col);
		if (word == null) {
			word = new Word(col);
			DataMaps.words.put(col, word);
		} else {
			word.incrementCount();
		}
		HashMap<Tag, Integer> map = emissionTable.get(word);
		if (map == null) {
			map = new HashMap<Tag, Integer>();
			emissionTable.put(word, map);
		}
		Tag tag = DataMaps.tags.get(row);
		if (tag == null) {
			tag = new Tag(row);
			DataMaps.tags.put(row, tag);
		}
		Integer count = map.get(tag);
		if (count == null) {
			map.put(tag, 1);
		} else {
			map.put(tag, count + 1);
		}
	}

	public int getCount(String row, String col) {
		Word word = DataMaps.words.get(col);
		if (word != null) {
			HashMap<Tag, Integer> hashMap = emissionTable.get(word);
			if (hashMap != null) {
				Tag tag = DataMaps.tags.get(row);
				if (tag != null) {
					Integer integer = hashMap.get(tag);
					if (integer != null) {
						return integer;
					}
				}
			}
		}
		return 0;
	}

	/**
	 * Usage: getProbability(tag, word) = Prob(word/tag)
	 */
	public double getProbability(String row, String col) {
		int countOfColGivenRow = getCount(row, col);
		if (countOfColGivenRow != 0) {
			//Word word = DataMaps.words.get(col);
			Tag word = DataMaps.tags.get(row);
			return ((double) countOfColGivenRow / (double) word.getCount());
		}
		return 0;
	}

	public double getProbability_lapsmoothing(String row, String col) {
		double countOfColGivenRow = (double)getCount(row, col);
		countOfColGivenRow += 0.00001; // Laplace Smoothing
		if (countOfColGivenRow != 0.0) {
			//Word word = DataMaps.words.get(col);
			Tag word = DataMaps.tags.get(row);
			double countOfWords = 0;
			if( word != null )
				countOfWords = (double) word.getCount() ;
//			countOfWords += Config.nTotalTags; // Laplace Smoothing
			countOfWords += 0.00001*DataMaps.words.size(); // Laplace Smoothing
			return ((double) countOfColGivenRow / (double) countOfWords);
		}
		return 0;
	}

	public double getProbability_ignore(String row, String col) {
		Word word1 = DataMaps.words.get(col);
		if(word1 == null ) return 0.1; // return constant prob for unknown words
		int countOfColGivenRow = getCount(row, col);
		if (countOfColGivenRow != 0) {
			Tag word = DataMaps.tags.get(row);
			int countOfWords = 0;
			if( word != null )
				countOfWords = word.getCount() ;
			return ((double) countOfColGivenRow / (double) countOfWords);
		}
		return 0;
	}
	
}
